package com.sanri.tools.modules.core.service.collect;

import com.alibaba.fastjson.JSON;
import com.sanri.tools.modules.core.service.plugin.PluginManager;
import com.sanri.tools.modules.core.service.plugin.dtos.EnhancePlugin;
import com.sanri.tools.modules.core.service.plugin.dtos.PluginCallInfo;
import com.sanri.tools.modules.core.utils.NetUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Map;

/**
 * 插件使用情况数据采集
 */
@Slf4j
@Component
public class PluginUseCollect implements DataCollect , InitializingBean {
	@Autowired
	private PluginManager pluginManager;

	@Value("${collect.ip:localhost}")
	private String ip;
	@Value("${collect.port:8084}")
	private int port;
	@Value("${collect.enable:false}")
	private boolean enable;

	private Socket socket;
	private BufferedWriter bufferedWriter;

	@Autowired
	private JavaMailSender mailSender;

	@Override
	public void collect() {
		if (!enable) {
            return ;
        }
		final Map<String, EnhancePlugin> pluginRegisterMap = pluginManager.getPluginRegisterMap();
		final String userIp = NetUtil.getLocalIPs().get(0);

		StringBuffer stringBuffer = new StringBuffer();
		for (EnhancePlugin enhancePlugin : pluginRegisterMap.values()) {
			PluginCallInfo pluginCallInfo = enhancePlugin.getPluginCallInfo();
			stringBuffer.append(pluginCallInfo.getPluginId())
					.append(":")
					.append(pluginCallInfo.getTotalCalls())
					.append(":")
					.append(DateFormatUtils.ISO_8601_EXTENDED_DATETIME_TIME_ZONE_FORMAT.format(pluginCallInfo.getLastCallTime()))
					.append(":")
					.append(pluginCallInfo.getLastCallTime())
					.append("\n");
			;
		}
		// 数据上报, 通过 socket
		final UserDataCollectClient.CollectData collectData = new UserDataCollectClient.CollectData(userIp, PluginUseCollect.class.getSimpleName(), stringBuffer.toString());

		try {
			// 首先试下邮件发送
			try {
				sendMail(collectData);
			}catch (Exception e){}

			bufferedWriter.write(JSON.toJSONString(collectData));
			bufferedWriter.write('\n');
		} catch (Exception e) {
//			log.error("数据推送流异常:{}", e.getMessage());

			this.reconnect();
		}

	}

	/**
	 * 邮件方式发送插件使用情况
	 * @param pluginUseData
	 */
	private void sendMail(UserDataCollectClient.CollectData pluginUseData) {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom("ningxiangsanri@163.com");
		message.setTo("ningxiangsanri@163.com");
		message.setSubject("插件使用情况:"+NetUtil.getLocalIPs().get(0));
		message.setText(JSON.toJSONString(pluginUseData, true));
		mailSender.send(message);
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		this.reconnect();
	}

	public void reconnect(){
        if (!enable) {
            return ;
        }

		if (bufferedWriter != null){
			try {
				bufferedWriter.close();
			} catch (IOException e) {
				// ignore
			}
		}
		if (socket != null){
			try{
				socket.close();
			} catch (IOException e) {
				// ignore
			}
		}

		try {
//			log.info("开始连接数据收集地址: {}:{}",ip,port);
			socket = new Socket(ip, port);

			final OutputStream outputStream = socket.getOutputStream();
			this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
		} catch (IOException e) {
//			log.error("连接数据推送地址失败: {}", e.getMessage());
		}
	}
}